package cn.eeepay.boss.action;

import cn.eeepay.boss.system.DataSource;
import cn.eeepay.boss.system.SystemLog;
import cn.eeepay.framework.db.pagination.Page;
import cn.eeepay.framework.model.*;
import cn.eeepay.framework.service.AccountAddressService;
import cn.eeepay.framework.service.AccountAddressTaskService;
import cn.eeepay.framework.service.AddressMappingService;
import cn.eeepay.framework.service.AreaInfoService;
import cn.eeepay.framework.util.Constants;
import cn.eeepay.framework.util.ListDataExcelExport;
import cn.eeepay.framework.util.ResponseUtil;
import cn.eeepay.framework.util.StringUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.ss.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

@Controller
@RequestMapping("/accountAddress")
public class AccountAddressAction {

	private static final Logger log = LoggerFactory.getLogger(AccountAddressAction.class);
	@Resource
	private AccountAddressService accountAddressService;
	@Resource
	private AreaInfoService areaInfoService;
	@Resource
	private AccountAddressTaskService accountAddressTaskService;
	@Resource
	private AddressMappingService addressMappingService;


	//查询账单地
	@RequestMapping(value = "/getAccountAreaMappings.do")
	@ResponseBody
	public Page<AccountAddress> getAccountAreaMappings(@ModelAttribute("page") Page<AccountAddress> page){
		try {
			List<AccountAddress> accountAddressList = accountAddressService.select(page);
			if(CollectionUtil.isNotEmpty(accountAddressList)){
				for (AccountAddress accountAddress : accountAddressList) {
					String address = accountAddress.getAddress();
					if(accountAddress.getAddressType() == 1){
						AreaInfo areaInfo = areaInfoService.getProvinceByCityName(address);
						accountAddress.setProvince(areaInfo.getName());
						accountAddress.setCity(address);
					}else{
						accountAddress.setProvince(address);
					}
				}
			}
		}catch (Exception e){
			log.error("查询账单地设置失败", e);
		}
		return page;
	}


	//账单地导出
	@DataSource(Constants.DATA_SOURCE_SLAVE)
	@RequestMapping("/accountAreaMappingsExport.do")
	@SystemLog(operCode = "accountAddress.export", description = "账单地导出")
	public void accountAreaMappingsExport(HttpServletResponse response){
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss") ;
			OutputStream ouputStream = null;
			try {
				Page<AccountAddress> page = new Page(0, Integer.MAX_VALUE);
				List<AccountAddress> accountAddressList = accountAddressService.select(page);
				int size = 2;
				ListDataExcelExport export = new ListDataExcelExport(size);
				String fileName = "账单地" + sdf.format(new Date()) + export.getFileSuffix(size);
				String fileNameFormat = new String(fileName.getBytes(),"ISO-8859-1");
				response.setHeader("Content-disposition", "attachment;filename="+fileNameFormat);
				response.setContentType("application/vnd.ms-excel;charset=utf-8");
				List<Map<String, String>> data = new ArrayList<>();

				for (AccountAddress accountAddress : accountAddressList) {
					Map<String,String> map = new HashMap<>();
					map.put("address",accountAddress.getAddress());
					String addressType = accountAddress.getAddressType() == 1 ? "是" : "否";
					map.put("addressType",addressType);
					map.put("totalAmount",accountAddress.getTotalAmount().toString());
					map.put("reservedAmount",accountAddress.getReservedAmount().toString());
					map.put("releaseTime",accountAddress.getReleaseTimeStr());
					String startTime = DateUtil.formatTime(accountAddress.getStartTime());
					String endTime = DateUtil.formatTime(accountAddress.getEndTime());
					map.put("transTimeStart",startTime);
					map.put("transTimeEnd",endTime);
					map.put("transAmountMin",accountAddress.getMinAmount().toString());
					map.put("transAmountMax",accountAddress.getMaxAmount().toString());
					String joinGroupPolling = accountAddress.getJoinGroupPolling() == 0 ? "参与" : "不参与";
					map.put("joinGroupPolling",joinGroupPolling);
					String openStatus = accountAddress.getOpenStatus() == 0 ? "关" : "开";
					map.put("openStatus",openStatus);
					data.add(map);
				}
				String[] cols = new String[]{
						"address","addressType","totalAmount","reservedAmount","releaseTime","transTimeStart","transTimeEnd","transAmountMin","transAmountMax","joinGroupPolling","openStatus"
				};
				String[] colsName = new String[]{
						"账单地","是否单列市","账单地额度(元)","预留额度(元)","预留额度释放时间","交易起始时间","交易结束时间","交易最小金额","交易最大金额","不参与集群轮循","启用状态"
				};
				ouputStream = response.getOutputStream();
				export.export(cols, colsName, data, response.getOutputStream());
			} catch (Exception e) {
				log.error("账单地导出导出异常", e);
			} finally {
				if(ouputStream!=null){
					try {
						ouputStream.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		} catch (Exception e){
			log.error("账单地导出导出异常", e);
		}
	}

	@RequestMapping(value="/save.do")
	@ResponseBody
	@SystemLog(description = "保存账单地",operCode="accountAddress.save")
	public Result save(@RequestBody String params){
		try {
			AccountAddress accountAddress = JSONObject.parseObject(params, AccountAddress.class);

			if(StrUtil.isNotBlank(accountAddress.getCity()) && !accountAddress.getCity().equals("请选择")){
				accountAddress.setAddress(accountAddress.getCity());
				accountAddress.setAddressType(1);
			}else{
				accountAddress.setAddress(accountAddress.getProvince());
				accountAddress.setAddressType(0);
			}

			String address = accountAddress.getAddress();
			if(accountAddressService.findAccountAddressByAddress(address) != null){
				return Result.fail("添加账单地失败,账单地不能重复");
			}

			accountAddress.setReservedAmount(accountAddress.getReservedAmount().multiply(new BigDecimal("10000")));
			accountAddress.setLocalUsed(BigDecimal.ZERO);
			accountAddress.setOtherUsed(BigDecimal.ZERO);
			accountAddress.setCreateTime(new Date());
			if(accountAddressService.insert(accountAddress) > 0){
				return Result.success("添加账单地成功");
			}
		} catch (Exception e) {
			log.error("添加账单地失败: ",e);
		}
		return Result.fail("添加账单地失败");
	}


	@RequestMapping(value="/update.do")
	@ResponseBody
	@SystemLog(description = "修改账单地",operCode="accountAddress.update")
	public Result update(@RequestBody String params){
		try {
			AccountAddress accountAddress = JSONObject.parseObject(params, AccountAddress.class);

			if(StrUtil.isNotBlank(accountAddress.getCity()) && !accountAddress.getCity().equals("请选择")){
				accountAddress.setAddress(accountAddress.getCity());
				accountAddress.setAddressType(1);
			}else{
				accountAddress.setAddress(accountAddress.getProvince());
				accountAddress.setAddressType(0);
			}

			String address = accountAddress.getAddress();
			AccountAddress accountAddressByAddress = accountAddressService.findAccountAddressByAddress(address);
			if(accountAddressByAddress != null){
				Integer id = accountAddressByAddress.getId();
				if(id.intValue() != accountAddress.getId().intValue()){
					return Result.fail("修改账单地失败,账单地不能重复");
				}
			}

			accountAddress.setReservedAmount(accountAddress.getReservedAmount().multiply(new BigDecimal("10000")));
			accountAddress.setLastUpdateTime(new Date());
			if(accountAddressService.update(accountAddress) > 0){
				return Result.success("修改账单地成功");
			}
		} catch (Exception e) {
			log.error("修改账单地失败: ",e);
		}
		return Result.fail("修改账单地失败");
	}

	//查询账单地
	@RequestMapping(value = "/findAddressSetting.do")
	@ResponseBody
	public Result findAddressSetting(Integer id){
		Result result = Result.fail();
		try {
			List<AccountAddressTask> accountAddressList = accountAddressTaskService.select(id);
			if(CollectionUtil.isNotEmpty(accountAddressList)){
				for (AccountAddressTask accountAddressTask : accountAddressList) {
					Date effectiveTime = accountAddressTask.getEffectiveTime();
					String effectiveTimeStr = DateUtil.formatDateTime(effectiveTime);
					accountAddressTask.setEffectiveTimeStr(effectiveTimeStr);
				}
			}
			result = Result.success(null,accountAddressList);
		}catch (Exception e){
			log.error("查询账单地设置失败", e);
			result = ResponseUtil.buildResult(e);
		}
		return result;
	}

	@RequestMapping(value="/saveAddress.do")
	@ResponseBody
	@SystemLog(description = "账单地额度设置",operCode="accountAddress.saveAddress")
	public Result saveAddress(@RequestBody String params){
		try {
			JSONObject jsonObject = JSONObject.parseObject(params);
			JSONArray addressGroup = jsonObject.getJSONArray("addressGroup");
			String address = jsonObject.getString("address");
//			List<AccountAddressTask> accountAddress = JSONObject.parseArray(params, AccountAddressTask.class);
			List<AccountAddressTask> accountAddress = addressGroup.toJavaList(AccountAddressTask.class);
			accountAddressTaskService.saveOrUpdate(address,accountAddress);
			return Result.success("保存账单地额度成功");
		} catch (Exception e) {
			log.error("保存账单地额度失败: ",e);
		}
		return Result.fail("保存账单地额度失败");
	}

	@RequestMapping(value="/updateJoinGroupPollingStatus")
	@ResponseBody
	@SystemLog(description = "账单地集群轮询设置",operCode="accountAddress.updateJoinGroupPollingStatus")
	public Result updateJoinGroupPollingStatus(@RequestParam("id") Integer id,@RequestParam("status") Integer status){
		try {
			accountAddressService.updateJoinGroupPollingStatus(id,status);
			return Result.success("成功");
		} catch (Exception e) {
			log.error("失败: ",e);
		}
		return Result.fail("成功");
	}

	@RequestMapping(value="/updateOpenStatus")
	@ResponseBody
	@SystemLog(description = "账单地启用状态设置",operCode="accountAddress.updateOpenStatus")
	public Result updateOpenStatus(@RequestParam("id") Integer id,@RequestParam("status") Integer status){
		try {
			accountAddressService.updateOpenStatus(id,status);
			return Result.success("成功");
		} catch (Exception e) {
			log.error("失败: ",e);
		}
		return Result.fail("成功");
	}

	//查询账单地
	@RequestMapping(value = "/getAccountAddressTaskList.do")
	@ResponseBody
	public Page<AccountAddressTask> getAccountAddressTaskList(Integer accountAddressId,@ModelAttribute("page") Page<AccountAddressTask> page){
		try {
			accountAddressTaskService.selectByAccountAddressId(accountAddressId,page);
		}catch (Exception e){
			log.error("查询账单地设置失败", e);
		}
		return page;
	}


	@DataSource(Constants.DATA_SOURCE_SLAVE)
	@RequestMapping(value="/page.do")
	@ResponseBody
	public Page<AddressMapping> list(@RequestParam("jumpId") Integer jumpId,@ModelAttribute("page") Page<AddressMapping> page){
		try {
			addressMappingService.list(jumpId,page);
		} catch (Exception e) {
			log.error("条件查询跳转集群配置列表失败",e);
		}
		return page;
	}

	@DataSource(Constants.DATA_SOURCE_SLAVE)
	@RequestMapping(value="/initMappingAddress.do")
	@ResponseBody
	public Page<AddressMapping> initMappingAddress(){
		Page<AddressMapping> page = new Page<>();
		try {
			List<AreaInfo> allProvince = areaInfoService.getAllProvince();
			List<AddressMapping> list = new ArrayList<>();
			for (AreaInfo areaInfo : allProvince) {
				AddressMapping am = new AddressMapping();
				String name = areaInfo.getName();
				am.setRegisterAddressParent(name);
				am.setRegisterAddress(name);
				am.setRegisterAddressType(0);
				am.setItems("[]");
				am.setItemsDatail("[]");
				am.setJoinAreaPolling(1);
				list.add(am);
			}
			page.setResult(list);
		} catch (Exception e) {
			log.error("条件查询跳转集群配置列表失败",e);
		}
		return page;
	}

	@RequestMapping(value="/addressMappingSave.do")
	@ResponseBody
	@SystemLog(description = "映射地区保存",operCode="accountAddress.addressMappingSave")
	public Result addressMappingSave(@RequestBody String params){
		Result result = Result.fail();
		try {
			JSONObject.parseObject(params);
//			int num = jumpRouteSevice.save(params);
//			if(num == 1){
//				result = Result.success();
//			}
		} catch (Exception e) {
			log.error("映射地区保存失败", e);
			result = ResponseUtil.buildResult(e);
		}
		return result;
	}

	/**
	 * 账单地设置模板下载
	 */
	@RequestMapping("/downloadTemplate")
	public String downloadAdjustAccTemplate(HttpServletRequest request, HttpServletResponse response) {
		String filePath = request.getServletContext().getRealPath("/") + File.separator + "template" + File.separator + "accountAddressSetTemplate.xlsx";
		ResponseUtil.download(response, filePath, "账单地设置模板.xlsx");
		return null;
	}



	/**
	 * 账单地区导入
	 *
	 * @return
	 * @throws Exception
	 */
	@SystemLog(description = "账单地区导入",operCode="accountAddress.import")
	@RequestMapping("/accountAddressMappingImport")
	@ResponseBody
	public Result accountAddressMappingImport(@RequestParam("file") MultipartFile file) {
		Result result = new Result();
		log.info("=====账单地区导入");
		try {
			Workbook wb = WorkbookFactory.create(file.getInputStream());
			Sheet sheet = wb.getSheetAt(0);
			int row_num = sheet.getLastRowNum();
			List<String> list = new ArrayList<>();
			List<AccountAddress> amList = new ArrayList<>();
			for (int i = 1; i <= row_num; i++) {
				AccountAddress am = new AccountAddress();
				Row row = sheet.getRow(i);

				Cell cell0 = row.getCell(0);
				if (cell0 == null) {
					continue;
				}
				String address = cell0.getStringCellValue();			//账单地
				if (StringUtil.isEmpty(address)) {
					continue;
				}
				am.setAddress(address);

				if(list.contains(address)){
					String errorMessage = String.format("账单地\"%s\"重复",address);
					result.setStatus(false);
					result.setMsg(errorMessage);
					return result;
				}else{
					list.add(address);
				}

				Cell cell1 = row.getCell(1);
				String address_type = cell1.getStringCellValue();
				if (StringUtil.isEmpty(address_type)) {
					continue;
				}
				int type = StrUtil.isNotEmpty(address_type) && address_type.equals("否") ? 0 : 1;
				am.setAddressType(type);

				if(type == 0) {		//非单例市
					AreaInfo province = areaInfoService.getProvinceByName(address);
					if(province == null){
						String errorMessage = String.format("未找到账单地\"%s\"",address);
						result.setStatus(false);
						result.setMsg(errorMessage);
						return result;
					}
				}else{			//单列市
					AreaInfo areaInfo = areaInfoService.getProvinceByCityName(address);
					if(areaInfo == null){
						String errorMessage = String.format("未找到账单地\"%s\"",address);
						result.setStatus(false);
						result.setMsg(errorMessage);
						return result;
					}
				}

				Cell cell2 = row.getCell(2);
				cell2.setCellType(Cell.CELL_TYPE_STRING);
				String total_amount = cell2.getStringCellValue();
				if (StringUtil.isEmpty(total_amount)) {
					continue;
				}
				BigDecimal totalAmount = new BigDecimal(total_amount);			//账单地额度
				am.setTotalAmount(totalAmount);

				Cell cell3 = row.getCell(3);
				cell3.setCellType(Cell.CELL_TYPE_STRING);
				String reserved_amount = cell3.getStringCellValue();
				if (StringUtil.isEmpty(reserved_amount)) {
					continue;
				}
				am.setReservedAmount(new BigDecimal(reserved_amount));		//预留额度

				Cell cell4 = row.getCell(4);
				String release_time = "";
				if(cell4.getCellType() == HSSFCell.CELL_TYPE_NUMERIC){
					double dateCellValueDouble = cell4.getNumericCellValue();
					Date dateCellValue = org.apache.poi.ss.usermodel.DateUtil.getJavaDate(dateCellValueDouble);
					release_time = DateUtil.formatTime(dateCellValue);		//预留额度释放时间
				}else{
					cell4.setCellType(Cell.CELL_TYPE_STRING);
					release_time = cell4.getStringCellValue();
				}
				if(StrUtil.isNotBlank(release_time)){
					am.setReleaseTime(DateUtil.parseTime(release_time));
					am.setReleaseTimeStr(release_time);
				}

				Cell cell5 = row.getCell(5);

				String transTimeStart = "";
				if(cell5.getCellType() == HSSFCell.CELL_TYPE_NUMERIC){
					double dateCellValueDouble = cell5.getNumericCellValue();
					Date dateCellValue = org.apache.poi.ss.usermodel.DateUtil.getJavaDate(dateCellValueDouble);
					transTimeStart = DateUtil.formatTime(dateCellValue);		//交易起始时间
				}else{
					cell5.setCellType(Cell.CELL_TYPE_STRING);
					transTimeStart = cell5.getStringCellValue();
				}
				if(StrUtil.isNotBlank(transTimeStart)){
					am.setStartTime(DateUtil.parseTime(transTimeStart));
					am.setStartTimeStr(transTimeStart);
				}

				Cell cell6 = row.getCell(6);

				String transTimeEnd = "";
				if(cell6.getCellType() == HSSFCell.CELL_TYPE_NUMERIC){
					double dateCellValueDouble = cell6.getNumericCellValue();
					Date dateCellValue = org.apache.poi.ss.usermodel.DateUtil.getJavaDate(dateCellValueDouble);
					transTimeEnd = DateUtil.formatTime(dateCellValue);		//交易结束时间
				}else{
					cell6.setCellType(Cell.CELL_TYPE_STRING);
					transTimeEnd = cell6.getStringCellValue();
				}
				if(StrUtil.isNotBlank(transTimeEnd)){
					am.setEndTime(DateUtil.parseTime(transTimeEnd));
					am.setEndTimeStr(transTimeEnd);
				}

				if(am.getStartTime().getTime() >= am.getEndTime().getTime()){
					String errorMessage = String.format("账单地\"%s\"交易时间不能跨天",address);
					result.setStatus(false);
					result.setMsg(errorMessage);
					return result;
				}

				Cell cell7 = row.getCell(7);
				cell7.setCellType(Cell.CELL_TYPE_STRING);
				String transAmountMin = cell7.getStringCellValue();			//交易金额区间
				if(StrUtil.isNotBlank(transAmountMin)){
					am.setMinAmount(new BigDecimal(transAmountMin));
				}

				Cell cell8 = row.getCell(8);
				cell8.setCellType(Cell.CELL_TYPE_STRING);
				String transAmountMax = cell8.getStringCellValue();			//交易金额区间
				if(StrUtil.isNotBlank(transAmountMax)){
					am.setMaxAmount(new BigDecimal(transAmountMax));
				}

				Cell cell9 = row.getCell(9);
				String join_group_polling = cell9.getStringCellValue();
				if (StringUtil.isEmpty(join_group_polling)) {
					continue;
				}
				int joinGroupPolling = StrUtil.isNotEmpty(join_group_polling) && join_group_polling.equals("不参与") ? 1 : 0;
				am.setJoinGroupPolling(joinGroupPolling);

				Cell cell10 = row.getCell(10);
				String open_status = cell10.getStringCellValue();
				if (StringUtil.isEmpty(open_status)) {
					continue;
				}
				int openStatus = StrUtil.isNotEmpty(open_status) && open_status.equals("关") ? 0 :1;
				am.setOpenStatus(openStatus);

				am.setLocalUsed(BigDecimal.ZERO);
				am.setOtherUsed(BigDecimal.ZERO);
				am.setCreateTime(new Date());
				amList.add(am);
			}

			accountAddressService.insertExport(amList);

			result.setStatus(true);
			result.setMsg("导入成功");
		} catch (Exception e) {
			log.error("accountAddressMappingImport.error", e);
			result.setMsg("模版错误，导入失败");
		}
		return result;
	}


}
